/**
 ******************************************************************************
 * @file           : bsp_timer.c
 * @brief          : Timer Driver Implementation (STM32F4xx)
 ******************************************************************************
 * @attention
 *
 * 定时器驱动实现文件
 * 支持微秒级定时中断
 *
 ******************************************************************************
 */

/* Includes ------------------------------------------------------------------*/
#include "./BSP/TIMER/bsp_timer.h"
#include "./BSP/TIMER/bsp_timer_config.h"

/* Private includes ----------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
static TIM_HandleTypeDef sg_timer_handle;
static timer_callback_t sg_timer_callback = NULL;
static volatile TIMER_Error_e sg_timer_state = TIMER_OK;  /*!< 定时器状态 */
static volatile uint8_t sg_timer_running = 0;             /*!< 定时器是否运行 */

/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/

/**
 * @brief       定时器初始化
 *
 * @param[in]   period_us 定时周期（微秒）
 *
 * @retval      无
 *
 * @note        配置定时器产生周期性中断
 */
void timer_init(uint32_t period_us)
{
    uint32_t prescaler;
    uint32_t period;
    uint32_t timer_clock;

    /* 使能定时器时钟 */
    TIMER_TIMx_CLK_ENABLE();

    /* 计算定时器时钟频率（考虑APB倍频） */
    timer_clock = TIMER_APB_CLOCK * 2;  /* APB1预分频后，定时器时钟×2 */

    /* 计算预分频值和周期值 */
    /* 目标：1MHz计数频率（1us精度） */
    prescaler = timer_clock / 1000000 - 1;  /* 预分频到1MHz */
    period = period_us - 1;                  /* 周期值 */

    /* 配置定时器基础参数 */
    sg_timer_handle.Instance = TIMER_TIMx;
    sg_timer_handle.Init.Prescaler = prescaler;
    sg_timer_handle.Init.CounterMode = TIM_COUNTERMODE_UP;
    sg_timer_handle.Init.Period = period;
    sg_timer_handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    sg_timer_handle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;

    if (HAL_TIM_Base_Init(&sg_timer_handle) != HAL_OK)
    {
        log_e("Timer initialization failed");
        return;
    }

    /* 配置中断优先级并使能 */
    HAL_NVIC_SetPriority(TIMER_TIMx_IRQn, 2, 0);
    HAL_NVIC_EnableIRQ(TIMER_TIMx_IRQn);

    log_i("Timer%d initialized: %u us", TIMER_SELECT_NUM, period_us);
}

/**
 * @brief       定时器去初始化
 *
 * @param       无
 *
 * @retval      无
 */
void timer_deinit(void)
{
    /* 停止定时器 */
    HAL_TIM_Base_Stop_IT(&sg_timer_handle);

    /* 禁用中断 */
    HAL_NVIC_DisableIRQ(TIMER_TIMx_IRQn);

    /* 去初始化定时器 */
    HAL_TIM_Base_DeInit(&sg_timer_handle);

    /* 清除回调函数 */
    sg_timer_callback = NULL;

    log_i("Timer%d deinitialized", TIMER_SELECT_NUM);
}

/**
 * @brief       启动定时器
 *
 * @param       无
 *
 * @retval      无
 */
void timer_start(void)
{
    if (HAL_TIM_Base_Start_IT(&sg_timer_handle) != HAL_OK)
    {
        log_e("Timer start failed");
        sg_timer_state = TIMER_ERROR_HAL;
    }
    else
    {
        sg_timer_running = 1;
        sg_timer_state = TIMER_OK;
        log_d("Timer%d started", TIMER_SELECT_NUM);
    }
}

/**
 * @brief       停止定时器
 *
 * @param       无
 *
 * @retval      无
 */
void timer_stop(void)
{
    HAL_TIM_Base_Stop_IT(&sg_timer_handle);
    sg_timer_running = 0;
    log_d("Timer%d stopped", TIMER_SELECT_NUM);
}

/**
 * @brief       设置定时器回调函数
 *
 * @param[in]   callback 回调函数指针
 *
 * @retval      无
 */
void timer_set_callback(timer_callback_t callback)
{
    sg_timer_callback = callback;
}

/**
 * @brief       定时器中断服务函数
 *
 * @param       无
 *
 * @retval      无
 *
 * @note        在stm32f4xx_it.c中调用此函数
 */
void TIMER_TIMx_IRQHandler(void)
{
    /* 检查更新中断标志 */
    if (__HAL_TIM_GET_FLAG(&sg_timer_handle, TIM_FLAG_UPDATE) != RESET)
    {
        /* 清除中断标志 */
        __HAL_TIM_CLEAR_IT(&sg_timer_handle, TIM_IT_UPDATE);

        /* 调用用户回调函数 */
        if (sg_timer_callback != NULL)
        {
            sg_timer_callback();
        }
    }
}

/**
 * @brief       获取定时器状态
 *
 * @param       无
 *
 * @retval      定时器错误码
 */
TIMER_Error_e timer_get_state(void)
{
    return sg_timer_state;
}

/**
 * @brief       打印定时器状态（调试接口）
 *
 * @param       无
 *
 * @retval      无
 */
void timer_print_status(void)
{
    const char *state_str[] = {
        "OK",
        "ERROR_PARAM",
        "ERROR_HAL"
    };
    
    if (sg_timer_state < 3)
    {
        log_i("Timer State: %s", state_str[sg_timer_state]);
    }
    else
    {
        log_i("Timer State: UNKNOWN");
    }
    
    log_i("Timer Running: %s", sg_timer_running ? "YES" : "NO");
}
